Vital Sign

Row

Vital Sign

Row

Description

This is the density plot showing the patient’s status (0 = alive, 1 = death) of each vital sign.

 

Take the vital sign “Heart Rate” as an example,

 
  • Patients who survived have heart rate reaches the peak at approximately 80 (i.e.[79, 80.99]), with 63 patients alive.
 
  • While patients who didn’t survive have heart rate reaches the peak at approximately 90 (i.e.[85, 89.99]), with 23 patients dead.
 
  • Both density distributions are symmetric with bell-shaped.

Boxplot

Comorbidities

Row

Comorbidities

Row

Description

This is the stacked bar chart showing the patient’s status (0 = alive, 1 = death) of each comorbities.

 

Take the comorbities “Hypertensive” as an example,

 
  • Patients who alive have higher proportion (prop. = 0.7305801) to be diagnosed as hypertensive compared to patients who didn’t survive (prop. = 0.6352201) .

Lab Results Analysis

Row

Lab Results Analysis

Row

Description

This is the density plot showing the patient’s status (0 = alive, 1 = death) of each “lab result analysis”.

 

Take the analysis of “Creatinine” as an example,

 
  • Patients who survived have creatinine level reaches the peak at approximately 1 (i.e.[1, 1.199]), with 164 patients alive.
 
  • While patients who didn’t survive have creatinine level reaches the peak at approximately 0.75 (i.e.[0.5, 0.999] and [1, 1.499]), with 76 patients dead (38 for each).
 
  • Both density distributions are right skewed with long tails.

Boxplot

### PCA Analysis

Row

PCA Analysis

Row

Description

This is the scatter plot with a color gradient legend, showing the significance contributions of each variable at two dimensions.

 

Take choosing “Anion Gap”, “Bicarbonate”, “Leucocyte”, “Neutrophils”, “RBC” and “Creatinine” as an example,

 
  • Their contributions from significant to insignificant is: “Anion Gap” > “Bicarbonate” > “Leucocyte” > “Creatinine” > “Neutrophils” > “RBC”.
 
  • Importantly, “Bicarbonate” contributed most at Dim2, up to 21.3%.
 
  • While “Neutrophils” has least contributions at Dim1 (33.8%).
---
title: "Mortality Dashboard"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    source_code: embed
runtime: shiny
---

```{r setup, include=FALSE}
library(flexdashboard)
library(tidyverse)
library(plotly)
library(shiny)
library(data.table)
library(reshape2)
library(rsconnect)
library(FactoMineR)
library(factoextra)

# read the data
mortality_data <- 
  read_csv("mortality_data_cleaned.csv")

# Change the factor variables for EDA 

col_names <- c("group", "outcome", "hypertensive", 
                         "atrialfibrillation", "chd_with_no_mi", "diabetes", 
                         "deficiencyanemias", "depression", "hyperlipemia", 
                         "renal_failure", "copd")

mortality_data[,col_names] <- lapply(mortality_data[,col_names] , factor)


# Manually recoding factors to their meaningful character values
mortality_data_EDA <- mortality_data %>%
  mutate(
    group = recode(group, `1` = "Group 1", `2` = "Group 2"),
    gender = recode(gender, `1` = "Male", `2` = "Female"),
    outcome = recode(outcome, `0` = "Alive", `1` = "Death")
  ) %>%
  mutate_if(is.factor, as.character) # Converts all remaining factors to characters

# Function to recode factor variables to 'Yes' or 'No'
convert_factors_to_yes_no <- function(df, comorbidity_columns) {
  df <- df %>%
    mutate(across(all_of(comorbidity_columns), ~ ifelse(as.character(.) == "1", "Yes", "No")))
  return(df)
}

# List of comorbidity columns to convert
comorbidity_columns <- c("hypertensive", "atrialfibrillation", "chd_with_no_mi", 
                         "diabetes", "deficiencyanemias", "depression", 
                         "hyperlipemia", "renal_failure", "copd")

# Apply the function to the mortality_data_EDA dataframe
mortality_data_EDA <- convert_factors_to_yes_no(mortality_data_EDA, comorbidity_columns)


# function to correct the title format 
formatVarName <- function(variable) {
  variable <- gsub("_", " ", variable)  # Replace underscores with spaces
  variable <- tools::toTitleCase(variable)  # Capitalize the first letter of each word
  return(variable)
}

#select patient vital signs
sign_tidy =
  mortality_data_EDA |>
  select(outcome, heart_rate:ef)
```


Vital Sign
===================================== 

Column {.sidebar}
-----------------------------------------------------------------------


```{r}
selectInput(
    inputId = "vital_sign_index_x",
    label = h3("Select Index"),
    choices = c("Heart Rate" = "heart_rate", 
                "Systolic Blood Pressure" = "systolic_blood_pressure", 
                "Diastolic Blood Pressure" = "diastolic_blood_pressure", 
                "Respiratory Rate" = "respiratory_rate", 
                "Temperature" = "temperature", 
                "SpO2" = "sp_o2", 
                "Urine Output" = "urine_output"),
    selected = "heart_rate"
  )

```




Row{data-height=650}
-----------------------------------------------------------------------

### Vital Sign

```{r}

renderPlotly({
    variable <- input$vital_sign_index_x
    formattedVarName <- formatVarName(variable)
  
    plot_ly(data = mortality_data_EDA %>% drop_na(.data[[variable]]),
            x = ~.data[[variable]],
            color = ~as.factor(outcome),
            type = 'histogram',
            opacity = 0.6) %>%
      layout(barmode = "overlay",
             title = paste(formattedVarName, "Levels by Outcome"),
             xaxis = list(title = formattedVarName),
             yaxis = list(title = "Density"))
  })


```

Row {.tabset .tabset-fade}
-------------------------------------


### Description


This is the density plot showing the patient's status (0 = alive, 1 = death) of each vital sign. 

\ \par
Take the vital sign "Heart Rate" as an example,

\ \par
  * Patients who survived have heart rate reaches the peak at approximately 80 (i.e.[79, 80.99]), with 63 patients alive.
  
\ \par
  * While patients who didn't survive have heart rate reaches the peak at approximately 90 (i.e.[85, 89.99]), with 23 patients dead.
  
\ \par
  * Both density distributions are symmetric with bell-shaped.
  
### Boxplot

```{r}
renderPlotly({
  variable <- input$vital_sign_index_x
  formattedVarName <- formatVarName(variable)
  
  plot_ly(mortality_data_EDA %>% drop_na(.data[[variable]]), 
          x = ~as.factor(outcome),
          y = ~.data[[variable]],
          color = ~as.factor(outcome),
          type = "box") %>%
    layout(title = paste(formattedVarName, "Levels by Outcome"),
           xaxis = list(title = "Outcome"),
           yaxis = list(title = formattedVarName))
})

```



Comorbidities
===================================== 

Column {.sidebar}
-----------------------------------------------------------------------

```{r}
selectInput(
    inputId = "como_index_y",
    label = h3("Select Comorbidity"),
    choices = c("Hypertensive" = "hypertensive", 
                "Atrialfibrillation" = "atrialfibrillation", 
                "CHD with no MI"= "chd_with_no_mi",
                "Diabetes" = "diabetes", 
                "Deficiencyanemias"= "deficiencyanemias", 
                "Depression"= "depression", 
                "Hyperlipemia"= "hyperlipemia", 
                "Renal Failure"= "renal_failure", 
                "COPD"= "copd"),
    selected = "hypertensive"
  )


```


Row{data-height=650}
-----------------------------------------------------------------------

### Comorbidities

```{r}
comorbidities <- c("hypertensive", "atrialfibrillation", "chd_with_no_mi", 
                         "diabetes", "deficiencyanemias", "depression", 
                         "hyperlipemia", "renal_failure", "copd")

renderPlotly({
    variable <- input$como_index_y
    formattedVarName <- formatVarName(variable)
    # Melt the data into a long format for plotting
    mortality_long <- melt(mortality_data_EDA, id.vars = "outcome", measure.vars = comorbidities)
    
    # Filter for the selected comorbidity
    filtered_data <- mortality_long %>% 
      filter(variable == input$como_index_y) %>%
      mutate(Count = ifelse(value == "Yes", 1, 0)) %>%
      group_by(outcome, variable) %>%
      summarise(Yes = sum(Count), No = n() - sum(Count)) %>%
      gather(key = "Presence", value = "Count", -outcome, -variable)
    
    # Create the stacked bar chart
    plot_ly(data = filtered_data, 
            x = ~outcome, 
            y = ~Count, 
            color = ~Presence, 
            type = 'bar', 
            text = ~paste(Count, "cases"), 
            hoverinfo = 'text+x+y') %>%
      layout(title = paste("Distribution of", formattedVarName, "by Outcome"),
             yaxis = list(title = "Count"),
             xaxis = list(title = formattedVarName),
             barmode = 'stack')
  })
```


```{r eval=FALSE}
renderPlotly({
  variable <- input$como_index_y
  formattedVarName <- formatVarName(variable)

    # Create the stacked bar chart
    plot_ly(data = mortality_long, 
            x = ~variable, 
            y = ~value, 
            color = ~outcome, 
            type = 'bar', 
            text = ~paste(value, "cases")) %>%
      layout(yaxis = list(title = "Count"), 
             barmode = 'stack', 
             xaxis = list(title = ""))
  })

```

Row {.tabset .tabset-fade}
-------------------------------------


### Description


This is the stacked bar chart showing the patient's status (0 = alive, 1 = death) of each comorbities. 

\ \par
Take the comorbities "Hypertensive" as an example,

\ \par
  * Patients who alive have higher proportion (prop. = `r 743/(743+274)`) to be diagnosed as hypertensive compared to patients who didn't survive (prop. = `r 101/(101+58)`) .


Lab Results Analysis
===================================== 

Column {.sidebar}
-----------------------------------------------------------------------


```{r}
selectInput(
    inputId = "index",
    label = h3("Select Index"),
    choices = c("Creatinine" = "creatinine", 
                "Lactic Acid" = "lactic_acid", 
                "Urea Nitrogen" = "urea_nitrogen", 
                "Leucocyte" = "leucocyte", 
                "Glucose" = "glucose", 
                "Anion Gap" = "anion_gap", 
                "PCO2" = "pco2"),
    selected = "creatinine"
  )

```




Row{data-height=650}
-----------------------------------------------------------------------

### Lab Results Analysis

```{r}

renderPlotly({
    variable <- input$index
    formattedVarName <- formatVarName(variable)
  
    plot_ly(data = mortality_data_EDA %>% drop_na(.data[[variable]]),
            x = ~.data[[variable]],
            color = ~as.factor(outcome),
            type = 'histogram',
            opacity = 0.6) %>%
      layout(barmode = "overlay",
             title = paste(formattedVarName, "Levels by Outcome"),
             xaxis = list(title = formattedVarName),
             yaxis = list(title = "Density"))
  })



```

Row {.tabset .tabset-fade}
-------------------------------------


### Description

This is the density plot showing the patient's status (0 = alive, 1 = death) of each "lab result analysis". 

\ \par
Take the analysis of "Creatinine" as an example,

\ \par
  * Patients who survived have creatinine level reaches the peak at approximately 1 (i.e.[1, 1.199]), with 164 patients alive.
  
\ \par
  * While patients who didn't survive have creatinine level reaches the peak at approximately 0.75 (i.e.[0.5, 0.999] and [1, 1.499]), with 76 patients dead (38 for each).
  
\ \par
  * Both density distributions are right skewed with long tails.
  
### Boxplot

```{r}
renderPlotly({
  variable <- input$index
  formattedVarName <- formatVarName(variable)
  
  plot_ly(mortality_data_EDA %>% drop_na(.data[[variable]]), 
          x = ~as.factor(outcome),
          y = ~.data[[variable]],
          color = ~as.factor(outcome),
          type = "box") %>%
    layout(title = paste(formattedVarName, "Levels by Outcome"),
           xaxis = list(title = "Outcome"),
           yaxis = list(title = formattedVarName))
})

```


### PCA Analysis
===================================== 

Column {.sidebar}
-----------------------------------------------------------------------

```{r}
checkboxGroupInput(
    inputId = "PCA",
    label = h3("Select Index"),
    choices = c(
      "Anion Gap" = "anion_gap", 
      "Blood Calcium" = "blood_calcium", 
      "Bicarbonate" = "bicarbonate", 
      "Lactic Acid" = "lactic_acid", 
      "Leucocyte" = "leucocyte", 
      "Lymphocyte" = "lymphocyte", 
      "Neutrophils" = "neutrophils", 
      "RBC" = "rbc", 
      "MCH" = "mch", 
      "Urea Nitrogen" = "urea_nitrogen", 
      "Hematocrit" = "hematocrit", 
      "Creatinine" = "creatinine"),
    selected = c("anion_gap", "neutrophils", "bicarbonate", "leucocyte", "creatinine", "rbc")
  )
```


Row{data-height=650}
-----------------------------------------------------------------------

### PCA Analysis

```{r}
renderPlotly({
    variable <- input$PCA
    formattedVarName <- formatVarName(variable)
  
    pca_coord = 
      PCA(sign_tidy |> select(variable), scale.unit = TRUE, graph = FALSE)
    
    fviz_pca_var(pca_coord, col.var = "contrib", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")) |> ggplotly()
  })
```

Row {.tabset .tabset-fade}
-------------------------------------


### Description

This is the scatter plot with a color gradient legend, showing the significance contributions of each variable at two dimensions. 

\ \par
Take choosing "Anion Gap", "Bicarbonate", "Leucocyte", "Neutrophils", "RBC" and "Creatinine" as an example,

\ \par
  * Their contributions from significant to insignificant is: "Anion Gap" > "Bicarbonate" > "Leucocyte" > "Creatinine" > "Neutrophils" > "RBC".
  
\ \par
  * Importantly, "Bicarbonate" contributed most at Dim2, up to 21.3%.
  
\ \par
  * While "Neutrophils" has least contributions at Dim1 (33.8%).